In [1]:
import this
In the above we ran one line of code and out popped a poem, and as we go through the course more and more lines of this poem should start to make sense to you. But before all that, let's talk about 'import'.
The Import statement is basically us saying to the computer:
"Hey Python, can you go fetch to other bit of code that someone else wrote? thanx mate."
In this particular case, we are importing something called "this". Python has a few easter-eggs and inside jokes dotted around the place, you can read about the history of how ‘import this’ became a thing by clicking here.
Anyway, the syntax for importing code is below.
import {Name of module we wish to import}
Anyway, I digress; the actual focus of today's lecture is to study the meaning of two lines found within Tim Peter's poem.
Part One will speak about readability, part two will talk about the distinction between implicit/explicit code.
On numerous occasions throughout this course I will refer to the idea that readability matters, indeed, we have already seen the importance of good names, but readability has a much larger scope than that. Most of my lectures will focus on how code can made more readable, but in this lecture I want to try to explain why readability counts.
The TLDR version:
The second bullet point is a bit cryptic, but once I’ve finished explaining it will make sense, I promise.
Alright, let’s imagine we are trying to build the ‘perfect’ bit of software. What properties would it have? Its an abstract question, but here are a free of my ideas of what 'perfect code' would look like.
So that’s a nice list of qualities that exemplary software would have. The interesting thing to note here is that readability helps with every single one of these bullet points.
Take the first point, performance, how does readability help here?
Well, imagine being handed a novel with all the pages out of order. Think about how much harder and how much more time consuming understanding that novel would be relative to being given a copy with the correct page numbers; working with messy code is very much like the disordered novel. If the code is messy the development team has to spend a lot of time just understanding how the pieces fit together, they have to do that before they can actually go about making meaningful performance improvements. The readable code meanwhile is understood in a much shorter space of time, therefore our team of hypothetical developers can thus spend more of their time and energy focused on the actual task at hand.
In short, the less developers have to wonder about how something works, the more time they have to innervate, tinker, and toy with the code. The result (over long periods of time) is faster code with fewer bugs and more features.
The lesson here is that readability isn’t a ‘nice-to-have extra’, rather, it's a core ingredient for great code. And so, when writing code I want you guys to always ask yourself the following two questions:
If you keep on asking yourself these two basic questions when writing code then you'll be writing good code in no time at all!
In short, bugs and security flaws often lurk in the shadows. So, one way to avoid these problems is to avoid the number of shadows there are in the first place. In this analogys, the shadows refer to confusing bits of code that are difficult to understand. Complexity obscures things, simplicity reveals the truth.
Here's a quick attempt to show you that.
In [5]:
a = 7
b = (False * a) + a
c = a / b
So this code is a bit confusing. How can we simplify the code? Well, we can do this:
In [1]:
c = 1
In this above code snippet "False a number" is actually the same as "0 n", which is always zero. So 'b' is always '0 + a', which simplifies to just 'a'. And since 'a' divided by 'a' is always 1 (except when a is zero) we can actually just delete all the code and set c to 1.
Complex code becomes simple. And remember, bugs hide in complexity. We can see that clearly if we set a to zero:
In [4]:
a = 0
b = (False * a) + a
c = a / b
So, not only did simplifying the code make it easier to understand what was going on, the simplification also doesn't contain a zero division error. Its also faster. Okay, I must admit that this example was a bit contrived, but still, hopefully you get the idea; simple code is good, complex code is bad. Okay, lets look at another example:
POP QUIZ! Can you guys figure out what the following code snippet does?
In [ ]:
def f(m, a):
return m * a
The answer is probably no, and that's not particularly surprising since this code has two new keywords (def, return), indentation, and a few other bits of syntax we have yet to discuss. Tell you what, let's change the variable names to something better and see if you can figure it out then…
In [ ]:
def net_force(mass, acceleration):
return mass * acceleration
If you have managed to figure out what this code does then I’d say I’ve proven just how useful readability can be; despite you guys not know several bits of syntax a wise choice of variable names allowed you to figure what is (probably) going on.
If I were to rate it, I'd probably give this code a C+. The code seems correct, it is concise, and chose variable names wisely. However, the major drawback to this code is it doesn't use any defensive programming techniques and as a consequence the code may break when we give it unexpected input (the ‘operator overloading’ lecture will go into the specifics). Now, writing code without test cases or checks is acceptable in many cases, but having no tests/checks AND no documentation is just asking for trouble! Basically the problem with the above code is that it makes no effort to warn/protect from 'improper' usage.
Defensive programming is a style of writing code whereby you try to write code that ‘predicts’ errors and stops them from happening in the first place.
"Prevention is better than cure".
How can we prevent problems? Well, there are hundreds upon hundreds of ways to do that, but the code snippet above doesn’t try any of them.
That’s it for today, ‘Philosophy part two’ will elaborate even further about some of potential fixes to this code. Stay tuned folks!